package com.ailk.aee.pcc.server;

import com.ailk.aee.pcc.dao.TargetDao;
import com.ailk.aee.pcc.exception.TargetException;
import com.ailk.aee.pcc.utils.CacheUtils;
import com.asiainfo.simplecache.SimpleCache;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @author pengzhang
 */
@SuppressWarnings("unchecked")
@Component
public class TargetServer {

    @Autowired
    private TargetDao targetDao;

    private SimpleCache targetCache;

    private SimpleCache targetCacheList;

    /**
     * 增加 指标数据
     *
     * @param targetKey   指标名
     * @param channelName 渠道名
     * @param parentKey   指标父结点
     */
    public String addTarget(String targetKey, String targetName, String channelName,
                            String parentKey, String targetRule, int level, String value) {

        //cacheKey 缓存关键字
        String cacheKey = CacheUtils.getTargetCacheName(channelName, targetKey);
        String parentCachekKey = CacheUtils.getTargetCacheName(channelName, parentKey);

        BasicDBObject targetObj = targetDao.addTarget(
                targetKey, targetName, channelName, parentKey, level, cacheKey, targetRule, value);

        targetObj.put("cacheKey", cacheKey);

        //更新二级缓存
        targetCache.put(cacheKey, targetObj);

        //删除一级缓存
        targetCacheList.delete(parentCachekKey);

        return cacheKey;
    }

    /**
     * 查询当前用户的级别
     *
     * @param cacheKey
     * @return
     */
    public int queryTargetLevel(String cacheKey) {

        BasicDBObject basicDBObject = this.queryTargetInfo(cacheKey);
        if (basicDBObject == null || basicDBObject.get("level") == null) {
            throw new TargetException(cacheKey + " :level is null");
        }

        return basicDBObject.getInt("level");
    }

    public BasicDBObject queryTargetInfo(String cacheKey) {
        //从缓存中取
        Serializable serializable = targetCache.get(cacheKey);
        //查询用户的级别
        BasicDBObject targetObject = (BasicDBObject) serializable;
        if (targetObject == null) {
            targetObject = (BasicDBObject) targetDao.queryTargetByCacheKey(cacheKey);
            targetCache.put(cacheKey, targetObject);
        }

        return targetObject;
    }

    public ArrayList<DBObject> queryTargetListByParentCacheKey(String parentKey, String channelName, int start, int limit) {
        DBCursor dbObjects = targetDao.queryTargetListByParentCache(channelName, parentKey, start, limit);
        ArrayList<DBObject> result = new ArrayList<DBObject>();
        for (DBObject dbObject : dbObjects) {
            dbObject.removeField("_id");
            result.add(dbObject);
        }
        dbObjects.close();
        return result;
    }


    /**
     * 查询目标cache
     *
     * @param parentKey
     * @param channelName
     * @return
     */
    public ArrayList<BasicDBObject> queryTargetListByParentCacheKey(String parentKey, String channelName) {
        String parentCacheKey = CacheUtils.getTargetCacheName(channelName, parentKey);

        //从一级缓存中取数据
        Serializable serializable = targetCacheList.get(parentCacheKey);
        ArrayList<String> targetList = (ArrayList<String>) serializable;
        ArrayList<BasicDBObject> basicDBObjectList = new ArrayList<BasicDBObject>();

        if (targetList == null) {
            targetList = new ArrayList<String>();
            //取数据
            DBCursor dbObjects = targetDao.queryTargetListByParentCache(channelName, parentKey);
            if (dbObjects != null && dbObjects.size() > 0) {
                for (DBObject dbObject : dbObjects) {
                    String cacheKey = (String) dbObject.get("cacheKey");
                    targetList.add(cacheKey);
                    this.putTargetInfoToList(cacheKey, basicDBObjectList);
                }
            }
            dbObjects.close();
            targetCacheList.put(parentCacheKey, targetList);
        } else {
            for (String cacheKey : targetList) {
                this.putTargetInfoToList(cacheKey, basicDBObjectList);
            }
        }
        return basicDBObjectList;
    }

    private void putTargetInfoToList(String cacheKey, ArrayList<BasicDBObject> basicDBObjectList) {
        BasicDBObject basicDBObject = this.queryTargetInfo(cacheKey);
        if (basicDBObject == null) {
            return;
        }
        basicDBObject.removeField("_id");
        basicDBObjectList.add(basicDBObject);
    }

    public List<DBObject> queryParentTargetListByCacheKey(String parentKey, String channelName, int parentLevel, int childLevel) {

        List<DBObject> targetParentList = new ArrayList<DBObject>();
        String parentCacheKey = CacheUtils.getTargetCacheName(channelName, parentKey);

        while (childLevel > parentLevel) {
            BasicDBObject basicDBObject = this.queryTargetInfo(parentCacheKey);
            if (basicDBObject == null || basicDBObject.get("cacheKey") == null) {
                return targetParentList;
            }
            basicDBObject.remove("_id");
            targetParentList.add(basicDBObject);
            parentCacheKey = CacheUtils.getTargetCacheName(basicDBObject.getString("channelName"), basicDBObject.getString("parentKey"));
            childLevel--;
        }
        return targetParentList;
    }

    /**
     * 删除指标
     */
    public void deleteTarget(String cacheKey) {

        BasicDBObject basicDBObject = this.queryTargetInfo(cacheKey);
        String channelName = basicDBObject.getString("channelName");
        String parentKey = basicDBObject.getString("parentKey");
        String targetKey = basicDBObject.getString("targetKey");

        String parentCacheKey = CacheUtils.getTargetCacheName(channelName, parentKey);
        //从父结点的一级缓存中移除
        this.deleteTargetFromParentCacheList(parentCacheKey, cacheKey);
        //删除自己
        targetDao.deleteTarget(cacheKey);
        //删除自己二级缓存
        targetCache.delete(cacheKey);
        //删除自己的一级缓存
        targetCacheList.delete(cacheKey);
        //查询自己的子结点
        ArrayList<BasicDBObject> basicDBObjects = this.queryTargetListByParentCacheKey(targetKey, channelName);

        if (basicDBObjects == null || basicDBObjects.size() == 0) {
            return;
        }
        for (BasicDBObject dbObject : basicDBObjects) {
            this.deleteTarget(dbObject.getString("cacheKey"));
        }

    }

    /**
     * 从一级缓存中删除子指标
     *
     * @param parentCacheKey
     */
    public void deleteTargetFromParentCacheList(String parentCacheKey, String cacheKey) {
        Serializable serializable = targetCacheList.get(parentCacheKey);
        if (serializable == null) {
            return;
        }
        ArrayList<String> cacheKeyList = (ArrayList<String>) serializable;
        int position = -1;
        for (int i = 0; i < cacheKeyList.size(); i++) {
            String childCacheKey = cacheKeyList.get(i);
            if (cacheKey.equalsIgnoreCase(childCacheKey)) {
                position = i;
                break;
            }
        }
        if (position > -1) {
            cacheKeyList.remove(position);
        }
    }


    public void updateParentLeafState(String parentCacheKey) {
        BasicDBObject basicDBObject = this.queryTargetInfo(parentCacheKey);
        if (basicDBObject != null && basicDBObject.getBoolean("isLeaf")) {
            //更新leaf 为 false ;
            targetDao.updateLeaf(parentCacheKey, false);
            targetCache.delete(parentCacheKey);
        }
    }


}
